home *** CD-ROM | disk | FTP | other *** search
- name free
- page 60,132
- title 'FREE --- report free space on disk'
-
- ;FREE --- a utility to report free space on
- ; the default or selected disk drive.
- ;
- ;Requires PC-DOS or MS-DOS 2.0
- ;
- ;Used in the form:
- ;A>FREE [unit:]
- ;(item in square brackets is optional)
- ;
- ;version 1.0 July 1, 1984
- ;Copyright (c) 1984 by Ray Duncan
- ;May be freely reproduced for non-commercial use.
-
- cr equ 0dh ;ASCII carriage return
- lf equ 0ah ;ASCII line feed
- blank equ 20h ;ASCII space code
- eom equ '$' ;end of string marker
-
-
- ;Here we define a dummy segment containing lavbels
- ;for thedefault fiel control black and the command tail buffer,
- ;so that the main program can access those locations.
- ;
- psp segment para public 'PSP'
-
- org 05ch
- fcb label byte ;default file control block
-
- org 080h
- command label byte ;default command buffer
-
- psp ends
-
- cseg segment para public'CODE'
-
- assume cs:cseg,ds:psp,es:data,ss:stack
-
- get_drive proc near ;get drive selection, if any,
- ;otherwise obtain the identity
- ;of the current disk drive.
- ;Return drive (1=A,2=B,etc)in RL.
- ;
- mov al,fcb ;Pick up the drive code, parsed
- ;by DOS into the default file
- ;control block.
- or al,al ;Is it the default?
- jnz get_drive1 ;no, use it
- mov ah,19h ;Yes, get the actual current
- int 21h ;drive from PC-DOS.
- inc al ;Increment to match FCB code.
- get_drive1: ;Return drive code in RL.
- ret
- get_drive endp
-
- free proc far ;entry point from PC-DOS
- push ds ;Save OS:0000 for final
- xor ax,ax ;return to PC-DOS
- push ax
- mov ax,data ;make our data segment
- mov es,ax ;addressable via ES register.
- mov ah,30h ;check version of PC-DOS.
- int 21h
- cmp al,2
- jae free1 ;proceed, DOS 2.0 or greater.
- mov dx,offset msg2 ;DOS 1.x -- print error message
- mov ax,es ;and exit. First fix up DS register
- mov ds,ax ;;so error message is addressable.
- jmp free1
-
- free1: call get_drive ;get drive selection into DL.
- push es ;copy ES to Ds for remainder
- pop ds ;of the program...
- assume ds:data ;and tell assembler about it.
- mov dl,al
- add al,'A'-1 ;form drive letter from drive soce,
- mov outputb,al ;and put i into the ouput string.
- mov ah,36h ;nob call dos to get free disk space
- int 21h
- cmp ax,-1 ;was drive invalid?
- je free3 ;yes, go print error message
- ;drive was ok, so now registers are.
-
- ;RX=number of sectors per cluser
- ;BX=available clusters,
- ;CX=number of bytes per sector,
- ;DX=total clusters per drive.
- ;calculate free space:
- mul cx ;sectors per cluster * bytes/sector
- ;(we assume no overflow into DX
- mul bx ;then* available clusers
- mov si,offset (outputa+9)
- mov cx,10 ;CX = 10, radix for conversion
- call bin_to_asc ;convert free space value to ASCII,
- mov dx,offset output
- jmp free4 ;and print it out.
-
- free3: mov dx,offset msg1 ;illegal drive, print error
-
- free4: mov ah,9 ;prin the string whose address
- int 21h ;is in DX.
- ret ;then return to DOS.
-
- free endp
-
- ;Convert 32 bit binary value to ASCII string.
- ;
- ;Call with DX:AX = signed 32 but value
- ; CX = radix
- ; SI = last byte of area to store resulting string
- ; (make sure enough room is available to store
- ; the string in the radix you have selected.)
- ;
- ;Destroys RX,BX,CX,DX, and SI.
- ;
- bin_to_asc proc near ;convert DX:AX to ASCII.
- ;force storage of at least 1 digit.
- mov byte ptr [si],'0'
- or dx,dx ;test sign of 32 bit value,
- pushf ;and save sign on stack.
- jns bin1 ;jump if it was positive.
- not dx ;it was negative, take 2's complemen
-
- not ax ;of the value.
- add ax,1
- adc dx,0
- bin1: ;divide the 32 bit balue by the radi
-
- ;to extract the next digit for the
- ;forming string.
- mov bx,ax ;is the value zero yet?
- or bx,dx
- jz bin3 ;yes, we are done converting.
- call divide ;no, divide by radix.
- add bl,'0' ;convert the remainder to an ASCII
- cmp bl,'9' ;we might be converting to hex ASCII
-
- jle bin2 ;jump if in range 0-9,
- add bl,'A'-'9'-1 ;correct it if in range A-F.
- bin2: mov [si],bl ;store this character into string.
- ;to extract the next digit for the
- ;forming string.
- dec si ;back up throught string,
- jmp bin1 ;and so it again.
- bin3: ;restore sign flag,
- popf ;was original value negative?
- jns bin4 ;no, jump
- ;yes, store sign into ouput string.
- mov byte ptr[si],'-'
- bin4: ret ;back to caller.
- bin_to_asc endp
-
-
- ;General purpose 32 bit by 16 bit unsigned divide.
- ;This must be used instead of the plain machine unsigned divide
- ;for cases where the quotient may overflow 16 bits (for example,
- ;dividing 100,000 by 2). If called with a zero divisor, this
- ;routine returns the dividend unchanged and gives no warning.
- ;
- ;Call with DX:AX = 32 bit dividend
- ; CX = divisor
- ;
- ;Returns DX:AX = quotient
- ; BX = remainder
- ; CX = divisor (unchanged)
- ;
-
- divide proc near ;Divide DX:AX by CX
- jcxz div1 ;exit if divide by zero
- push ax ;0:dividend_upper/divisor
- mov ax,dx
- xor dx,dx
- div cx
- mov bx,ax ;BX = quotient1
- pop ax ;remainder1:dividend_lower.divisor
- div cx
- xchg bx,dx ;DX:RX = quotient1:quotient2
- div1: ret ;BX = remainder2
- divide endp
- cseg ends
-
-
- data segment para public 'DATA'
-
- output db cr,lf
- outputa db 10 dup(blank)
-
-
- db 'bytes free on drive'
-
-
- outputb db 'x:',cr,lf,eom
-
- msg1 db cr,lf
- db 'That disk drive does not exist.'
-
-
- db cr,lf,eom
-
- msg2 db cr,lf
- db 'Requires DOS version 2 or greater.'
-
-
-
- db cr,lf,eom
- data ends
-
- stack segment para stack 'STACK'
- db 64 dup (?)
-
- stack ends
-
- end free